﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace WXR2BlogML
{
	public class XhtmlToXmlUtils
	{
		private static readonly string[] html_entities = new String[]
		                                        	{
		                                        		"&quot;", "&apos;", "&amp;", "&lt;", "&gt;", "&nbsp;", "&iexcl;", "&curren;"
		                                        		, "&cent;", "&pound;", "&yen;", "&brvbar;", "&sect;", "&uml;", "&copy;",
		                                        		"&ordf;", "&laquo;", "&not;", "&shy;", "&reg;", "&trade;", "&macr;", "&deg;"
		                                        		, "&plusmn;", "&sup2;", "&sup3;", "&acute;", "&micro;", "&para;", "&middot;"
		                                        		, "&cedil;", "&sup1;", "&ordm;", "&raquo;", "&frac14;", "&frac12;",
		                                        		"&frac34;", "&iquest;", "&times;", "&divide;", "&Agrave;", "&Aacute;",
		                                        		"&Acirc;", "&Atilde;", "&Auml;", "&Aring;", "&AElig;", "&Ccedil;",
		                                        		"&Egrave;", "&Eacute;", "&Ecirc;", "&Euml;", "&Igrave;", "&Iacute;",
		                                        		"&Icirc;", "&Iuml;", "&ETH;", "&Ntilde;", "&Ograve;", "&Oacute;", "&Ocirc;",
		                                        		"&Otilde;", "&Ouml;", "&Oslash;", "&Ugrave;", "&Uacute;", "&Ucirc;",
		                                        		"&Uuml;", "&Yacute;", "&THORN;", "&szlig;", "&agrave;", "&aacute;",
		                                        		"&acirc;", "&atilde;", "&auml;", "&aring;", "&aelig;", "&ccedil;",
		                                        		"&egrave;", "&eacute;", "&ecirc;", "&euml;", "&igrave;", "&iacute;",
		                                        		"&icirc;", "&iuml;", "&eth;", "&ntilde;", "&ograve;", "&oacute;", "&ocirc;",
		                                        		"&otilde;", "&ouml;", "&oslash;", "&ugrave;", "&uacute;", "&ucirc;",
		                                        		"&uuml;", "&yacute;", "&thorn;", "&yuml;", "&OElig;", "&oelig;", "&Scaron;",
		                                        		"&scaron;", "&Yuml;", "&circ;", "&tilde;", "&ensp;", "&emsp;", "&thinsp;",
		                                        		"&zwnj;", "&zwj;", "&lrm;", "&rlm;", "&ndash;", "&mdash;", "&lsquo;",
		                                        		"&rsquo;", "&sbquo;", "&ldquo;", "&rdquo;", "&bdquo;", "&dagger;",
		                                        		"&Dagger;", "&hellip;", "&permil;", "&lsaquo;", "&rsaquo;", "&euro;"
		                                        	};

		private static readonly string[] xml_entities = new String[]
		                                       	{
		                                       		"&#34;", "&#39;", "&#38;", "&#60;", "&#62;", "&#160;", "&#161;", "&#164;",
		                                       		"&#162;", "&#163;", "&#165;", "&#166;", "&#167;", "&#168;", "&#169;",
		                                       		"&#170;", "&#171;", "&#172;", "&#173;", "&#174;", "&#8482;", "&#175;",
		                                       		"&#176;", "&#177;", "&#178;", "&#179;", "&#180;", "&#181;", "&#182;",
		                                       		"&#183;", "&#184;", "&#185;", "&#186;", "&#187;", "&#188;", "&#189;",
		                                       		"&#190;", "&#191;", "&#215;", "&#247;", "&#192;", "&#193;", "&#194;",
		                                       		"&#195;", "&#196;", "&#197;", "&#198;", "&#199;", "&#200;", "&#201;",
		                                       		"&#202;", "&#203;", "&#204;", "&#205;", "&#206;", "&#207;", "&#208;",
		                                       		"&#209;", "&#210;", "&#211;", "&#212;", "&#213;", "&#214;", "&#216;",
		                                       		"&#217;", "&#218;", "&#219;", "&#220;", "&#221;", "&#222;", "&#223;",
		                                       		"&#224;", "&#225;", "&#226;", "&#227;", "&#228;", "&#229;", "&#230;",
		                                       		"&#231;", "&#232;", "&#233;", "&#234;", "&#235;", "&#236;", "&#237;",
		                                       		"&#238;", "&#239;", "&#240;", "&#241;", "&#242;", "&#243;", "&#244;",
		                                       		"&#245;", "&#246;", "&#248;", "&#249;", "&#250;", "&#251;", "&#252;",
		                                       		"&#253;", "&#254;", "&#255;", "&#338;", "&#339;", "&#352;", "&#353;",
		                                       		"&#376;", "&#710;", "&#732;", "&#8194;", "&#8195;", "&#8201;", "&#8204;",
		                                       		"&#8205;", "&#8206;", "&#8207;", "&#8211;", "&#8212;", "&#8216;", "&#8217;",
		                                       		"&#8218;", "&#8220;", "&#8221;", "&#8222;", "&#8224;", "&#8225;", "&#8230;",
		                                       		"&#8240;", "&#8249;", "&#8250;", "&#8364;"
		                                       	};

		public static string XhtmlToXml(string xhtml)
		{
			//xhtml = Regex.Replace(xhtml, "<!DOCTYPE\\s.*>", "", RegexOptions.IgnoreCase);
			xhtml = Regex.Replace(xhtml, "&\\w+;", new MatchEvaluator(ReplaceEntity));

			return xhtml;
		}

		public static string RemoveXhtml(string xhtml)
		{
			xhtml = Regex.Replace(xhtml, "&\\w+;", new MatchEvaluator(RemoveHtmlEntity));

			return xhtml;
		}

		public static string RemoveAll(string xhtml)
		{
			xhtml = Regex.Replace(xhtml, "&\\w+;", new MatchEvaluator(RemoveHtmlEntity));
			xhtml = Regex.Replace(xhtml, "&#\\d+;", new MatchEvaluator(RemoveXmlEntity));

			return xhtml;
		}

		public static void XhtmlToXml(string srcfile, string destfile)
		{
			string data;
			using (StreamReader sr = new StreamReader(srcfile))
				 data = sr.ReadToEnd();
			string converted = XhtmlToXml(data);
			using (StreamWriter sw = new StreamWriter(destfile))
				sw.Write(converted);
		}

		static string ReplaceEntity(Match m)
		{
			int index = Array.IndexOf(html_entities, m.Value);

			if (index >= 0)
				return xml_entities[index];
			return m.Value;
		}

		static string RemoveHtmlEntity(Match m)
		{
			int index = Array.IndexOf(html_entities, m.Value);

			if (index >= 0)
				return string.Empty;
			return m.Value;
		}

		static string RemoveXmlEntity(Match m)
		{
			int index = Array.IndexOf(xml_entities, m.Value);

			if (index >= 0)
				return string.Empty;
			return m.Value;
		}
	}
}
